package edu.ccut.saturn.component;

import java.util.ArrayList;
import java.util.List;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;

import edu.ccut.saturn.component.impl.SaturnParameterContext;

/**
 * 定时任务管理者，能够创建、启动、暂停、恢复、停止任务。维护了运行期的所有任务和加载启动构件的列表。
 * 
 * @author 李佳伦
 * 
 * @version 1.0 2009.6.12
 * 
 * @see SaturnTask
 */
public class SaturnTaskManager {

	private static final String LOGGER_KEY_BUNDLE_SERVICE = SaturnLoggerManager.LOGGER_KEY_BUNDLE_SERVICE;

	protected static ILogger logger = SaturnLoggerManager.getInstance().getSaturnLogger(LOGGER_KEY_BUNDLE_SERVICE);

	private Scheduler scheduler;

	//所有任务的任务列表
	private List<SaturnTask> taskList = new ArrayList<SaturnTask>();

	//加载时启动的任务列表
	private List<IComponentInfo> loadStartComponentInfoList = new ArrayList<IComponentInfo>();

	public static final String STATE_START = "start"; // 启动
	public static final String STATE_PAUSE = "pause"; // 暂停

	private static SaturnTaskManager instance;

	static {
		instance = new SaturnTaskManager();
	}

	private SaturnTaskManager() {
		try {
			scheduler = new StdSchedulerFactory().getScheduler();
			scheduler.start();
			logger.debug("scheduler is start");
		} catch (SchedulerException e) {
			logger.error("create scheduler failed !! ", e);
		}
	}

	public static SaturnTaskManager getInstance() {
		return instance;
	}

	public void addLoadStartTimerComponentInfo(IComponentInfo componentInfo) {
		this.loadStartComponentInfoList.add(componentInfo);
	}

	public void loadStartComponent() {
		for (IComponentInfo componentInfo : this.loadStartComponentInfoList) {
			IParameterContext parameterContext = new SaturnParameterContext();
			try {
				IComponent component = componentInfo.createComponent();
				component.execute(parameterContext);
			} catch (Exception e) {
				logger.error("load start failed when execute component [" + componentInfo.getFullKey() +" ] !!", e);
			} 
		}
	}

	/**
	 * 创建任务，初始化job明细和job的触发器
	 * 
	 * @param TimerInfo，IParameterContext
	 * @throws Exception 
	 */
	public String create(SaturnData taskSaturnData,
			IParameterContext parameterContext) throws Exception {

		SaturnTask task = new SaturnTask();
		task.initTask(taskSaturnData, parameterContext);
		taskList.add(task);
		logger.debug("task " + task.getKey() + "create!");
		return task.getKey();
	}

	/**
	 * 启动任务，根据任务唯一标识从任务列表中获得任务实例，启动任务
	 * 
	 * @param key
	 */
	public void start(String key) {
		
		SaturnTask task = null;
		
		for(SaturnTask t : this.taskList) {
			if (key.equalsIgnoreCase(t.getKey())) {
				task = t;
			}
		}
		
		if (task != null) {

			try {
				scheduler.scheduleJob(task.getJobDetail(), task.getTrigger());
			} catch (SchedulerException e) {
				logger.error("start task failed ! the task key is "
						+ task.getKey(), e);
			}

			task.setState(STATE_START);
			logger.debug("task " + key + "start!");
		}
	}

	/**
	 * 停止任务，根据任务唯一标识从任务列表中获得任务实例，停止任务
	 * 
	 * @param key
	 */
	public void shutDown(String key) {
		SaturnTask task = this.getTaskByTaskKey(key);
		if (task != null) {
			Boolean delete = false;

			try {
				delete = scheduler.deleteJob(task.getJobDetail().getName(),
						task.getJobDetail().getGroup());
			} catch (SchedulerException e) {
				logger.error("delete task failed ! the task key is "
						+ task.getKey(), e);
			}

			if (delete) {
				taskList.remove(task);
				logger.debug("task " + key + "delete!");
			}
		}
	}

	/**
	 * 暂停任务，根据任务唯一标识从任务列表中获得任务实例，暂停任务
	 * 
	 * @param key
	 */
	public void standby(String key) {
		SaturnTask task = this.getTaskByTaskKey(key);
		if (task != null) {

			try {
				scheduler.pauseJob(task.getJobDetail().getName(), task
						.getJobDetail().getGroup());
			} catch (SchedulerException e) {
				logger.error("standby task failed ! the task key is "
						+ task.getKey(), e);
			}

			task.setState(STATE_PAUSE);
			logger.debug("task " + key + "standby!");
		}
	}

	/**
	 * 恢复任务，根据任务唯一标识从任务列表中获得任务实例，恢复任务
	 * 
	 * @param key
	 */
	public void resume(String key) {
		SaturnTask task = this.getTaskByTaskKey(key);
		if (task != null) {
			try {
				scheduler.resumeJob(task.getJobDetail().getName(), task
						.getJobDetail().getGroup());
			} catch (SchedulerException e) {
				logger.error("resume task failed ! the task key is "
						+ task.getKey(), e);
			}
			task.setState(STATE_START);
			logger.debug("task " + key + "resume!");
		}
	}
	
	/**
	 * 根据任务的key值获得任务信息（正在执行中的任务）
	 * 
	 * @param key
	 */
	public SaturnTask getTaskByTaskKey(String key) {
		for (SaturnTask task : getSaturnTaskList()) {
			if (key.equalsIgnoreCase(task.getKey())) {
				return task;
			}
		}
		return null;
	}

	/**
	 * 获得任务列表中正在执行的任务
	 * 
	 * @param key
	 */
	public List<SaturnTask> getSaturnTaskList() {

		for (SaturnTask task : this.taskList) {
			if (task.getTrigger().getNextFireTime() == null) {
				this.taskList.remove(task);
			}
		}

		return this.taskList;
	}
	
	/**
	 * 获得加载时启动的任务
	 * 
	 * @param key
	 */
	public List<IComponentInfo> getLoadStartTaskList() {		
	
		List<IComponentInfo> loadStartComponentList = null;	
		
		for (IComponentInfo componentInfo : this.loadStartComponentInfoList) {
			if ("true".equals(componentInfo.getLoadStart())) {
				loadStartComponentList.add(componentInfo);
			}
		}

		return loadStartComponentList;
	}
}
